﻿Public Class TNSNamesReader

    Private Const _OraRegKey As String = "SOFTWARE\ORACLE"

    Private _OraTNSnamesFiles As New Dictionary(Of String, String)
    Private _CurrentHome As String = ""
    Private _OraTNSnames As New List(Of String)

    Sub New()
        Dim rgkAllHome As RegistryKey = Registry.LocalMachine.OpenSubKey(_OraRegKey)
        If rgkAllHome IsNot Nothing Then
            For Each subkey As String In rgkAllHome.GetSubKeyNames()
                If subkey.StartsWith("KEY_") Then
                    Dim rgkOracleHome As RegistryKey = Registry.LocalMachine.OpenSubKey(_OraRegKey & "\" & subkey)
                    If Not rgkOracleHome.Equals("") Then
                        Dim tmpHome As String = rgkOracleHome.GetValue("ORACLE_HOME_NAME").ToString()
                        Dim sTNSnamesFilePath As String = rgkOracleHome.GetValue("ORACLE_HOME").ToString()

                        Dim sTNSnamesFile = sTNSnamesFilePath & "\NETWORK\ADMIN\TNSNAMES.ORA"
                        If Not (System.IO.File.Exists(sTNSnamesFile)) Then
                            sTNSnamesFile = sTNSnamesFilePath & "\NET80\ADMIN\TNSNAMES.ORA"
                        End If

                        If (System.IO.File.Exists(sTNSnamesFile)) Then
                            _OraTNSnamesFiles.Add(tmpHome, sTNSnamesFile)
                        End If
                    End If
                End If
            Next
        End If
        If _OraTNSnamesFiles.Count > 0 Then CurrentHome = _OraTNSnamesFiles.ElementAt(0).Key
    End Sub

    Public ReadOnly Property TNSnames() As List(Of String)
        Get
            Return _OraTNSnames
        End Get
    End Property

    Public ReadOnly Property OraHomes As List(Of String)
        Get
            Dim _OraHomes As New List(Of String)
            For Each item In _OraTNSnamesFiles
                _OraHomes.Add(item.Key)
            Next
            Return _OraHomes
        End Get
    End Property

    Public Property CurrentHome As String
        Get
            Return _CurrentHome
        End Get
        Set(ByVal value As String)
            If _OraTNSnamesFiles.ContainsKey(value) Then

                Dim RegExPattern As String = "[\n][\s]*[^\(][a-zA-Z0-9_.]+[\s]*=[\s]*\("
                Dim fiTNS As New System.IO.FileInfo(_OraTNSnamesFiles(value))
                If fiTNS.Exists AndAlso fiTNS.Length > 0 Then
                    _CurrentHome = value
                    _OraTNSnames.Clear()
                    For iCount As Integer = 0 To Regex.Matches(System.IO.File.ReadAllText(fiTNS.FullName), RegExPattern).Count - 1
                        _OraTNSnames.Add(Regex.Matches(System.IO.File.ReadAllText(fiTNS.FullName), RegExPattern)(iCount).Value.Trim().Substring(0, Regex.Matches(System.IO.File.ReadAllText(fiTNS.FullName), RegExPattern)(iCount).Value.Trim().IndexOf(" ")))
                    Next
                Else
                    Throw New Exception(String.Format("TNSnames not found in Oracle Home '{0}'.", value))
                End If
            Else
                Throw New Exception("Unknown Oracle Home.")
            End If
        End Set
    End Property

End Class
